package com.jhh.pay.center.actor;

import akka.actor.ActorRef;
import akka.dispatch.Mapper;
import akka.dispatch.OnComplete;
import akka.pattern.Patterns;
import akka.util.Timeout;
import com.jhh.pay.center.api.data.Result;
import com.jhh.pay.center.cfg.SpringAppContext;
import com.jhh.pay.center.model.TradeState;
import com.jhh.pay.center.service.cloud.message.TradeResult;
import com.jhh.pay.center.util.StringUtils;
import org.springframework.web.context.request.async.DeferredResult;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;

import java.util.concurrent.TimeUnit;

/**
 * @author tangxd
 * @Description: TODO
 * @date 2017/12/7
 */
public class ActorUtil {

    public static <T> Future<T> map(Future<Object> future) {
        return future.map(new Mapper<Object, T>() {
            @Override
            public T apply(Object result) {
                if (result == null) {
                    return null;
                }
                return (T) result;
            }
        }, SpringAppContext.actorSystem().dispatcher());
    }

    public static <T, R> DeferredResult<R> deferred(
            String actorBeanName,
            String actorName,
            Object data,
            int seconds,
            DeferredCompleteFunctional<T, R> func) {
        ActorRef actor = SpringAppContext.getActor(actorBeanName, actorName);
        Future<Object> future = Patterns.ask(actor, data, new Timeout(Duration.create(seconds, TimeUnit.SECONDS)));
        Future<T> f = map(future);
        DeferredResult<R> result = new DeferredResult<>();
        f.onComplete(new OnComplete<T>() {
            @Override
            public void onComplete(Throwable failure, T response) {
                func.invoke(failure, response, result);
            }
        }, SpringAppContext.actorSystem().dispatcher());
        return result;
    }
}
